package com.cn.util;
import com.alibaba.fastjson.JSONObject;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author y
 * @Datetime 2021/8/1 2:42
 */
@Component
public class TokenUtil {
    /**
     * 用户登录成功后生成Jwt
     * 使用Hs256算法  私匙使用用户密码
     *
     * @param id        标识
     * @param info      登录成功的user对象
     * @param ttlMillis jwt过期时间(单位ms)
     * @return
     */
    public  String createJWT(String id, String info, long ttlMillis) {
        //指定签名的时候使用的签名算法，也就是header那部分，jjwt已经将这部分内容封装好了。
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //创建payload的私有声明（根据特定的业务需要添加，如果要拿这个做验证，一般是需要和jwt的接收方提前沟通好验证方式的）

        //生成签名的时候使用的秘钥secret,这个方法本地封装了的，一般可以从本地配置文件中读取，切记这个秘钥不能外露。
        //它就是你服务端的私钥，在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
        String key = "123456";

        //生成签发人
//        String subject = user.getUserMailAddress();

        //下面就是在为payload添加各种标准声明和私有声明了
        //这里其实就是new一个JwtBuilder，设置jwt的body
        JwtBuilder builder = Jwts.builder()
                //如果有私有声明，一定要先设置这个自己创建的私有的声明，这个是给builder的claim赋值，一旦写在标准的声明赋值之后，就是覆盖了那些标准的声明的
//                .setClaims(claims)
                //设置jti(JWT ID)：是JWT的唯一标识，根据业务需要，这个可以设置为一个不重复的值，主要用来作为一次性token,从而回避重放攻击。
                .setId(id)
                //iat: jwt的签发时间
                .setIssuedAt(now)
                //代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为什么用户的唯一标志。
                .setSubject(info)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, key);
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis*1000;//过期间隔单位化为s
            Date exp = new Date(expMillis);
            //设置过期时间
            builder.setExpiration(exp);
        }
        return builder.compact();
    }


    /**
     * Token的解密
     *
     * @param token 加密后的token
     * @return
     */
    public  Claims parseJWT(String token) {
        //签名秘钥，和生成的签名的秘钥一模一样
        String key = "123456";
        //得到DefaultJwtParser
        Claims claims = Jwts.parser()
                //设置签名的秘钥
                .setSigningKey(key)
                //设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }


//    public static void main(String[] args) {
//        TokenUtil jwTutil = new TokenUtil();
//        Claims claims = jwTutil.parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJ0ZW1wbGF0ZV93ZWIiLCJpYXQiOjE2Mjc4NDI3MTMsInN1YiI6IntcInV4eDAwMlwiOlwiXFx1MDAxOVxcdTAwMURcXHUwMDEyLD1MXFx1MDAxMlxcdTAwMThcXHUwMDFDXFx1MDAxRVxcdTAwMUZcXHUwMDE2NFxcdTAwMTdcXHUwMDE5PlxcdTAwMDZcXHUwMDA1Q1xcdTAwMUM_XFx1MDAxNlxcdTAwMUVcXHUwMDAxTDw0QUFfNVxcdTAwMTJcIixcInV4eDAwMVwiOlwiYWRtaW5cIixcInV4eDAwNFwiOlwiMTU4ODIxNzY5ODFcIixcInV4eDAwM1wiOlwi6JKy5L-KXCIsXCJ1eHgwMDZcIjpcIjIwMjEtMDgtMDIgMDA6MDc6MDBcIixcInV4eDAwNVwiOlwiMzI5Mjg5MzA5QHFxLmNvbVwiLFwieHh6MDAxXCI6XCIzZGM0YTRjNS1jMzc4LTQ0MDAtYmRlNi0xNmUzMDhhYTA1YTRcIn0iLCJleHAiOjE2MjgwMjI3MTN9.uJafuWBNe8DCJ2dwyWs6qN-GSdKvUfeI6INrDFbEVzU");
//        String subject = claims.getSubject();
//        Message messgae = JSON.parseObject(subject, Message.class);
//        System.out.println(JSON.toJSONString(messgae));
//    }

    /**
     * 校验token
     * 在这里可以使用官方的校验
     *
     * @param token
     * @return
     */
    public  Boolean isVerify(String token) {
        try {
            //得到DefaultJwtParser
            Claims claims = Jwts.parser()
                    //设置签名的秘钥
                    .setSigningKey("123456")
                    //设置需要解析的jwt
                    .parseClaimsJws(token).getBody();
            return false;
        } catch (Exception e) {
            return false;
        }
    }

 /*   public String generalSubject(UxxVO uxxVO) {
        JSONObject jo = new JSONObject();
        jo.put("xxz001", uxxVO.getXxz001());
        jo.put("uxx001", uxxVO.getUxx001());
        jo.put("uxx002", uxxVO.getUxx002());
        jo.put("uxx003", uxxVO.getUxx003());
        jo.put("uxx004", uxxVO.getUxx004());
        jo.put("uxx005", uxxVO.getUxx005());
        jo.put("uxx006", uxxVO.getUxx006());
        jo.put("uxx008", uxxVO.getUxx008());
        return jo.toJSONString();
    }*/
}
